home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume22 / nn6.4 / part19 < prev    next >
Encoding:
Internet Message Format  |  1990-06-07  |  54.8 KB

  1. Subject:  v22i053:  NN Newsreader, release 6.4, Part19/21
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 87ea17b3 5c5fecc1 0fd3183b 6c9d0924
  5.  
  6. Submitted-by: "Kim F. Storm" <storm@texas.dk>
  7. Posting-number: Volume 22, Issue 53
  8. Archive-name: nn6.4/part19
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then feed it
  12. # into a shell via "sh file" or similar.  To overwrite existing files,
  13. # type "sh file -c".
  14. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  15. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  16. # Contents:  conf/s-fortune.h conf/s-template.h conf/s-umipsb.h dir.c
  17. #   execute.c global.h inews/Makefile inews/README.NN keymap.h
  18. #   man/nngoback.1 options.c pack_date.c proto.c
  19. # Wrapped by storm@texas.dk on Sun May  6 18:20:17 1990
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. echo If this archive is complete, you will see the following message:
  22. echo '          "shar: End of archive 19 (of 22)."'
  23. if test -f 'conf/s-fortune.h' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'conf/s-fortune.h'\"
  25. else
  26.   echo shar: Extracting \"'conf/s-fortune.h'\" \(3266 characters\)
  27.   sed "s/^X//" >'conf/s-fortune.h' <<'END_OF_FILE'
  28. X*******************************************************************
  29. X/*
  30. X *    This file is for Fortune 32:16 systems.
  31. X *    Use with m-m680x0.h file, but requires STRCSPN in config.h
  32. X *    The Fortune may have problems with the nested #ifdef:s in
  33. X *    regexp.c (STRCSPN + __STDC__).  If so remove the __STDC__ ifdef.
  34. X *
  35. X *    From thewev!root, July 9, 1989.
  36. X */
  37. X
  38. X
  39. X/*
  40. X *    Include header files containing the following definitions:
  41. X *
  42. X *         off_t, time_t, struct stat
  43. X */
  44. X
  45. X#include <sys/types.h>
  46. X#include <stat.h>
  47. X
  48. X
  49. X/*
  50. X *    Define if your system has system V like ioctls
  51. X */
  52. X
  53. X/* #define    HAVE_TERMIO            /* */
  54. X
  55. X/*
  56. X *    Define to use terminfo database.
  57. X *    Otherwise, termcap is used
  58. X */
  59. X
  60. X/* #define    USE_TERMINFO            /* */
  61. X
  62. X/*
  63. X *    Specify the library (or libraries) containing the termcap/terminfo
  64. X *    routines.
  65. X *
  66. X *    Notice:  nn only uses the low-level terminal access routines
  67. X *    (i.e. it does not use curses).
  68. X */
  69. X
  70. X#define TERMLIB    -ltermlib
  71. X
  72. X/*
  73. X *    Define HAVE_STRCHR if strchr() and strrchr() are available
  74. X */
  75. X
  76. X/* #define HAVE_STRCHR            /* */
  77. X
  78. X/*
  79. X *    Define if a signal handler has type void (see signal.h)
  80. X */
  81. X
  82. X/* #define    SIGNAL_HANDLERS_ARE_VOID    /* */
  83. X
  84. X/*
  85. X *    Define if signals must be set again after they are caught
  86. X */
  87. X
  88. X#define    RESET_SIGNAL_WHEN_CAUGHT    /* */
  89. X
  90. X/*
  91. X *    Define MICRO_ALARM to timeout in 0.1 seconds if possible
  92. X */
  93. X
  94. X#define MICRO_ALARM()    alarm(1)    /* System V */
  95. X/*#define MICRO_ALARM()    ualarm(100000,0)    /* BSD 4.3 */
  96. X
  97. X/*
  98. X *    Define if your system has BSD like job control (SIGTSTP works)
  99. X */
  100. X
  101. X/* #define HAVE_JOBCONTROL            /* */
  102. X
  103. X
  104. X/*
  105. X *    Define if your system has a 4.3BSD like syslog library.
  106. X */
  107. X
  108. X#undef HAVE_SYSLOG
  109. X
  110. X/*
  111. X *    Define if your system provides the "directory(3X)" access routines
  112. X *
  113. X *    If true, include the header file(s) required by the package below
  114. X *    (remember that <sys/types.h> or equivalent is included above)
  115. X *    Also typedef Direntry to the proper struct type.
  116. X */
  117. X
  118. X/* #define    HAVE_DIRECTORY            /* */
  119. X
  120. X/* #include <dirent.h>            /* System V */
  121. X#include <sys/dir.h>                /* BSD */
  122. X
  123. X/* typedef struct dirent Direntry;        /* System V */
  124. Xtypedef struct direct Direntry;        /* BSD */
  125. X
  126. X/*
  127. X *    Define if your system has a mkdir() library routine
  128. X */
  129. X
  130. X#define    HAVE_MKDIR            /* */
  131. X
  132. X
  133. X/*
  134. X *    Define HAVE_GETHOSTNAME if your system provides a BSD like
  135. X *    gethostname routine.
  136. X *    Otherwise, define HAVE_UNAME if uname() is avaiable.
  137. X *    As a final resort, define HOSTNAME to the name of your system
  138. X *    (in config.h).
  139. X */
  140. X
  141. X/* #define    HAVE_GETHOSTNAME    /* BSD systems */
  142. X
  143. X/* #define    HAVE_UNAME            /* System V */
  144. X
  145. X/*
  146. X *    Define DETATCH_TERMINAL to be a command sequence which
  147. X *    will detatch a process from the control terminal
  148. X *    Also include system files needed to perform this HERE.
  149. X *    If not possible, just define it (empty)
  150. X */
  151. X
  152. X/* #include "...." */
  153. X
  154. X#define    DETATCH_TERMINAL /* setpgrp(); */
  155. X
  156. X
  157. X/*
  158. X *    Specify where the Bourne Shell is.
  159. X */
  160. X
  161. X#define SHELL        "/bin/sh"
  162. X
  163. X/*
  164. X *    Specify the default mailer to be invoked by nnmail
  165. X */
  166. X
  167. X#define    MAILX        "/bin/mail"    /* FOR:PRO */
  168. X/* #define    MAILX    "/usr/ucb/Mail"        /* BSD */
  169. X
  170. X/*
  171. X *    Define the maximum length of any pathname that may occur
  172. X */
  173. X
  174. X#define    FILENAME     128
  175. X
  176. X
  177. X/*
  178. X *    Define standard compiler flags here:
  179. X */
  180. X
  181. X#define COMPILER_FLAGS -O
  182. X
  183. X/*
  184. X *    If your system requires other libraries when linking nn
  185. X *    specify them here:
  186. X */
  187. X
  188. X#define EXTRA_LIB
  189. END_OF_FILE
  190.   if test 3266 -ne `wc -c <'conf/s-fortune.h'`; then
  191.     echo shar: \"'conf/s-fortune.h'\" unpacked with wrong size!
  192.   fi
  193.   # end of 'conf/s-fortune.h'
  194. fi
  195. if test -f 'conf/s-template.h' -a "${1}" != "-c" ; then 
  196.   echo shar: Will not clobber existing file \"'conf/s-template.h'\"
  197. else
  198.   echo shar: Extracting \"'conf/s-template.h'\" \(4660 characters\)
  199.   sed "s/^X//" >'conf/s-template.h' <<'END_OF_FILE'
  200. X/*
  201. X *    Use this file as a template for new s- files
  202. X */
  203. X
  204. X
  205. X/*
  206. X *    Include header files containing the following definitions:
  207. X *
  208. X *         off_t, time_t, struct stat
  209. X */
  210. X
  211. X#include <sys/types.h>
  212. X#include <sys/stat.h>
  213. X
  214. X
  215. X/*
  216. X *    Define if your system has system V like ioctls
  217. X */
  218. X
  219. X#define    HAVE_TERMIO            /* */
  220. X
  221. X/*
  222. X *    Define to use terminfo database.
  223. X *    Otherwise, termcap is used
  224. X */
  225. X
  226. X#define    USE_TERMINFO            /* */
  227. X
  228. X/*
  229. X *    Specify the library (or libraries) containing the termcap/terminfo
  230. X *    routines.
  231. X *
  232. X *    Notice:  nn only uses the low-level terminal access routines
  233. X *    (i.e. it does not use curses).
  234. X */
  235. X
  236. X#define TERMLIB    -ltermlib
  237. X
  238. X/*
  239. X *    Define HAVE_STRCHR if strchr() and strrchr() are available
  240. X */
  241. X
  242. X#define HAVE_STRCHR            /* */
  243. X
  244. X/*
  245. X *    Availability of varargs/vprintf/vsprintf is normally assumed
  246. X *    on most systems, *unless* NO_VARARGS is defined either here or
  247. X *    in the m- file.
  248. X *
  249. X *    To overrule a NO_VARARGS in the m- file, define HAVE_VARARGS
  250. X *    below if the varargs feature is available, *including* the
  251. X *    vprintf/vsprintf routines.
  252. X *
  253. X *    You may also define NO_VARARGS here, if varargs or the v*printf
  254. X *    are not available on this OS, but the m- file doesn't say so.
  255. X */
  256. X
  257. X/* #define HAVE_VARARGS /* Ignore NO_VARARGS -- else default */
  258. X/* #define NO_VARARGS /* */
  259. X
  260. X/*
  261. X *    Define if a signal handler has type void (see signal.h)
  262. X */
  263. X
  264. X#define    SIGNAL_HANDLERS_ARE_VOID    /* */
  265. X
  266. X/*
  267. X *    Define if signals must be set again after they are caught
  268. X */
  269. X
  270. X#define    RESET_SIGNAL_WHEN_CAUGHT    /* */
  271. X
  272. X/*
  273. X *    Define MICRO_ALARM to timeout in 0.1 seconds if possible
  274. X */
  275. X
  276. X#define MICRO_ALARM()    alarm(1)    /* System V */
  277. X/*#define MICRO_ALARM()    ualarm(100000,0)    /* BSD 4.3 */
  278. X
  279. X/*
  280. X *    Define if your system has BSD like job control (SIGTSTP works)
  281. X */
  282. X
  283. X/* #define HAVE_JOBCONTROL            /* */
  284. X
  285. X
  286. X/*
  287. X *    Define if your system has a 4.3BSD like syslog library.
  288. X */
  289. X
  290. X#undef HAVE_SYSLOG
  291. X
  292. X/*
  293. X *    Define if your system provides the "directory(3X)" access routines
  294. X *
  295. X *    If true, include the header file(s) required by the package below
  296. X *    (remember that <sys/types.h> or equivalent is included above)
  297. X *    Also typedef Direntry to the proper struct type.
  298. X */
  299. X
  300. X#define    HAVE_DIRECTORY            /* */
  301. X
  302. X#include <dirent.h>            /* System V */
  303. X/* #include <sys/dir.h>                /* BSD */
  304. X
  305. Xtypedef struct dirent Direntry;        /* System V */
  306. X/* typedef struct direct Direntry;        /* BSD */
  307. X
  308. X/*
  309. X *    Define if your system has a mkdir() library routine
  310. X */
  311. X
  312. X#define    HAVE_MKDIR            /* */
  313. X
  314. X
  315. X/*
  316. X *    Pick one:
  317. X *    Define HAVE_GETHOSTNAME if you have a BSD like gethostname routine.
  318. X *    Define HAVE_UNAME if a system V compatible uname() is available.
  319. X *    Define HOSTNAME_FILE "...." to a file containing the hostname.
  320. X *    Define HOSTNAME_WHOAMI if sysname is defined in <whoami.h>.
  321. X *
  322. X *    As a final resort, define HOSTNAME to the name of your system
  323. X *    (in config.h).
  324. X */
  325. X
  326. X/* #define HAVE_GETHOSTNAME            /* BSD systems */
  327. X/* #define HAVE_UNAME                /* System V */
  328. X/* #define HOSTNAME_FILE "/etc/uucpname"    /* or another file */
  329. X/* #define HOSTNAME_WHOAMI            /* in <whoami.h> */
  330. X
  331. X/*
  332. X *    Define HAVE_MULTIGROUP if system has simultaneous multiple group
  333. X *    membership capability (BSD style).
  334. X *    Also define NGROUPS or include the proper .h file if NGROUPS is
  335. X *    not defined in <sys/param.h>.
  336. X *    Also define GIDSET_TYPE to the type of the elements in the array
  337. X *    initialized by getgroups() if different from "int" (many systems
  338. X *    have a gid_t, but very few use it for getgroups()).
  339. X */
  340. X
  341. X/* #define HAVE_MULTIGROUP    /* BSD */
  342. X
  343. X/*
  344. X *    Define DETATCH_TERMINAL to be a command sequence which
  345. X *    will detatch a process from the control terminal
  346. X *    Also include system files needed to perform this HERE.
  347. X *    If not possible, just define it (empty)
  348. X */
  349. X
  350. X/* #include "...." */
  351. X
  352. X#define    DETATCH_TERMINAL /* setpgrp(); */
  353. X
  354. X
  355. X/*
  356. X *    Specify where the Bourne Shell is.
  357. X */
  358. X
  359. X#define SHELL        "/bin/sh"
  360. X
  361. X/*
  362. X *    Define OLD_AWK to the name of the "old awk" program if your
  363. X *    standard 'awk' is 'nawk' (new awk).  Use full path if necessary.
  364. X *    (This is a temporary hack until I get time to fix the scripts
  365. X *    which breaks nawk).
  366. X */
  367. X
  368. X/* #define OLD_AWK    "oawk"        /* */
  369. X
  370. X/*
  371. X *    Define AVOID_SHELL_EXEC if the system gets confused by
  372. X *        #!/bin/sh
  373. X *    lines in shell scripts, e.g. only reads #! and thinks it
  374. X *    is a csh script.
  375. X */
  376. X
  377. X/* #define AVOID_SHELL_EXEC        /* */
  378. X
  379. X/*
  380. X *    Specify the default mailer to be invoked by nnmail
  381. X */
  382. X
  383. X#define    MAILX        "/usr/bin/mailx"    /* SV */
  384. X/* #define    MAILX    "/usr/ucb/Mail"        /* BSD */
  385. X
  386. X/*
  387. X *    Define the maximum length of any pathname that may occur
  388. X */
  389. X
  390. X#define    FILENAME     256
  391. X
  392. X
  393. X/*
  394. X *    Define standard compiler flags here:
  395. X */
  396. X
  397. X#define COMPILER_FLAGS
  398. X
  399. X/*
  400. X *    If your system requires other libraries when linking nn
  401. X *    specify them here:
  402. X */
  403. X
  404. X#define EXTRA_LIB
  405. END_OF_FILE
  406.   if test 4660 -ne `wc -c <'conf/s-template.h'`; then
  407.     echo shar: \"'conf/s-template.h'\" unpacked with wrong size!
  408.   fi
  409.   # end of 'conf/s-template.h'
  410. fi
  411. if test -f 'conf/s-umipsb.h' -a "${1}" != "-c" ; then 
  412.   echo shar: Will not clobber existing file \"'conf/s-umipsb.h'\"
  413. else
  414.   echo shar: Extracting \"'conf/s-umipsb.h'\" \(4131 characters\)
  415.   sed "s/^X//" >'conf/s-umipsb.h' <<'END_OF_FILE'
  416. X/*
  417. X *    This is a file for Mips Risc/os, version 4.0 or later, for
  418. X *    compiling in the bsd43 (instead of sys v) environment.
  419. X *    From: beldar@mips.com (Gardner Cohen)
  420. X */
  421. X
  422. X
  423. X/*
  424. X *    Include header files containing the following definitions:
  425. X *
  426. X *         off_t, time_t, struct stat
  427. X */
  428. X
  429. X#include <sys/types.h>
  430. X#include <sys/stat.h>
  431. X
  432. X
  433. X/*
  434. X *    Define if your system has system V like ioctls
  435. X */
  436. X
  437. X#undef    HAVE_TERMIO            /* */
  438. X
  439. X/*
  440. X *    Define to use terminfo database.
  441. X *    Otherwise, termcap is used
  442. X */
  443. X
  444. X#undef    USE_TERMINFO            /* */
  445. X
  446. X/*
  447. X *    Specify the library (or libraries) containing the termcap/terminfo
  448. X *    routines.
  449. X *
  450. X *    Notice:  nn only uses the low-level terminal access routines
  451. X *    (i.e. it does not use curses).
  452. X */
  453. X
  454. X#define TERMLIB    -ltermcap
  455. X
  456. X/*
  457. X *    Define HAVE_STRCHR if strchr() and strrchr() are available
  458. X */
  459. X
  460. X#define HAVE_STRCHR            /* */
  461. X
  462. X/*
  463. X *    Define if a signal handler has type void (see signal.h)
  464. X */
  465. X
  466. X#undef    SIGNAL_HANDLERS_ARE_VOID    /* */
  467. X
  468. X/*
  469. X *    Define if signals must be set again after they are caught
  470. X */
  471. X
  472. X#undef    RESET_SIGNAL_WHEN_CAUGHT    /* */
  473. X
  474. X/*
  475. X *    Define MICRO_ALARM to timeout in 0.1 seconds if possible
  476. X */
  477. X
  478. X/*#define MICRO_ALARM()    alarm(1)    /* System V */
  479. X#define MICRO_ALARM()    ualarm(100000,0)    /* BSD 4.3 */
  480. X
  481. X/*
  482. X *    Define if your system has BSD like job control (SIGTSTP works)
  483. X */
  484. X
  485. X#define HAVE_JOBCONTROL            /* */
  486. X
  487. X
  488. X/*
  489. X *    Define if your system has a 4.3BSD like syslog library.
  490. X */
  491. X
  492. X#undef HAVE_SYSLOG
  493. X
  494. X/*
  495. X *    Define if your system provides the "directory(3X)" access routines
  496. X *
  497. X *    If true, include the header file(s) required by the package below
  498. X *    (remember that <sys/types.h> or equivalent is included above)
  499. X *    Also typedef Direntry to the proper struct type.
  500. X */
  501. X
  502. X#define    HAVE_DIRECTORY            /* */
  503. X
  504. X#include <sys/dir.h>                /* BSD */
  505. X
  506. Xtypedef struct direct Direntry;        /* BSD */
  507. X
  508. X/*
  509. X *    Define if your system has a mkdir() library routine
  510. X */
  511. X
  512. X#define    HAVE_MKDIR            /* */
  513. X
  514. X
  515. X/*
  516. X *    Define HAVE_GETHOSTNAME if your system provides a BSD like
  517. X *    gethostname routine.
  518. X *    Otherwise, define HAVE_UNAME if uname() is avaiable.
  519. X *    As a final resort, define HOSTNAME to the name of your system
  520. X *    (in config.h).
  521. X */
  522. X
  523. X#define    HAVE_GETHOSTNAME    /* BSD systems */
  524. X
  525. X/*
  526. X *    Define HAVE_MULTIGROUP if system has simultaneous multiple group
  527. X *    membership capability (BSD style).
  528. X *
  529. X *    Also define GIDSET_TYPE to the type of the elements in the array
  530. X *    initialized by getgroups() if different from "int" (many systems
  531. X *    have a gid_t, but very few use it for getgroups()).
  532. X */
  533. X
  534. X#define HAVE_MULTIGROUP
  535. X
  536. X#define GIDSET_TYPE    gid_t    /* Newer 4.3 systems may use this */
  537. X
  538. X/* #define    HAVE_UNAME            /* System V */
  539. X
  540. X/*
  541. X *    Define DETATCH_TERMINAL to be a command sequence which
  542. X *    will detatch a process from the control terminal
  543. X *    Also include system files needed to perform this HERE.
  544. X *    If not possible, just define it (empty)
  545. X */
  546. X
  547. X
  548. X#include <sys/file.h>    /* for O_RDONLY */
  549. X#include <sys/ioctl.h>    /* for TIOCNOTTY */
  550. X
  551. X#define    DETATCH_TERMINAL \
  552. X    { int t = open("/dev/tty", O_RDONLY); \
  553. X      if (t >= 0) ioctl(t, TIOCNOTTY, (int *)0), close(t); }
  554. X
  555. X
  556. X
  557. X/*
  558. X *    Specify where the Bourne Shell is.
  559. X */
  560. X
  561. X#define SHELL        "/bin/sh"
  562. X
  563. X/*
  564. X *    Define AVOID_SHELL_EXEC if the system gets confused by
  565. X *        #!/bin/sh
  566. X *    lines in shell scripts, e.g. only reads #! and thinks it
  567. X *    is a csh script.
  568. X */
  569. X
  570. X/* #define AVOID_SHELL_EXEC        /* */
  571. X
  572. X/*
  573. X *    Specify the default mailer to be invoked by nnmail
  574. X */
  575. X
  576. X#define    MAILX        "/usr/bin/mailx"    /* SV */
  577. X/* #define    MAILX    "/usr/ucb/Mail"        /* BSD */
  578. X
  579. X
  580. X/*
  581. X *    Specify the default pager & options.
  582. X */
  583. X
  584. X#define    PAGER        "less"
  585. X
  586. X/*
  587. X *    Specify the default print command and options.
  588. X */
  589. X
  590. X#define    PRINTER        "/usr/bin/lp -s"
  591. X
  592. X
  593. X/*
  594. X *    Define the maximum length of any pathname that may occur
  595. X */
  596. X
  597. X#define    FILENAME     1024
  598. X
  599. X
  600. X/*
  601. X *    Define standard compiler flags here:
  602. X */
  603. X#undef COMPILER_FLAGS
  604. X#undef COMPILER
  605. X#undef CDEBUG
  606. X#define COMPILER_FLAGS -O2 -Olimit 2000
  607. X#define COMPILER cc -systype bsd43
  608. X#define CDEBUG -g3
  609. X
  610. X/*
  611. X *    If your system requires other libraries when linking nn
  612. X *    specify them here:
  613. X */
  614. X
  615. X#define EXTRA_LIB
  616. X
  617. X/*
  618. X *    It is said that vprintf is missing from the bsd43 library
  619. X *    on MIPS/120 -- what a mess!    ++KFS
  620. X */
  621. X
  622. X#define NO_VARARGS
  623. END_OF_FILE
  624.   if test 4131 -ne `wc -c <'conf/s-umipsb.h'`; then
  625.     echo shar: \"'conf/s-umipsb.h'\" unpacked with wrong size!
  626.   fi
  627.   # end of 'conf/s-umipsb.h'
  628. fi
  629. if test -f 'dir.c' -a "${1}" != "-c" ; then 
  630.   echo shar: Will not clobber existing file \"'dir.c'\"
  631. else
  632.   echo shar: Extracting \"'dir.c'\" \(3623 characters\)
  633.   sed "s/^X//" >'dir.c' <<'END_OF_FILE'
  634. X/*
  635. X *    (c) Copyright 1990, Kim Fabricius Storm.  All rights reserved.
  636. X *
  637. X *    Directory access.
  638. X *     read file names in directory 'dir' starting with 'prefix'
  639. X */
  640. X
  641. X#include "config.h"
  642. X#include "articles.h"
  643. X#include "dir.h"
  644. X
  645. Xstatic char dir_path[FILENAME], *dir_tail;
  646. X
  647. X#ifdef HAVE_DIRECTORY
  648. X
  649. Xstatic string_marker str_mark;
  650. Xstatic char **completions = NULL;
  651. Xstatic char **comp_iterator;
  652. Xstatic char **comp_help;
  653. X
  654. X/*
  655. X * list_directory scans the directory twice; first time to find out how
  656. X * many matches there are, and second time to save the names, after
  657. X * sufficient memory have been allocated to store it all.
  658. X */
  659. X
  660. Xstatic sort_directory(f1, f2)        /* Used by [Dqsort */
  661. X    register char **f1;
  662. X    register char **f2;
  663. X{
  664. X    return strcmp(*f1, *f2);
  665. X}
  666. X
  667. Xlist_directory(dir, prefix)
  668. Xchar *dir, *prefix;
  669. X{
  670. X    DIR *dirp;
  671. X    register Direntry *dp;
  672. X    register char *cp;
  673. X    register char **comp;
  674. X    int pflen = strlen(prefix);
  675. X    unsigned count = 0, comp_length = 0;
  676. X
  677. X    if ((dirp = opendir(dir)) == NULL)
  678. X    return 0;            /* tough luck */
  679. X
  680. X    mark_str(&str_mark);
  681. X
  682. X    while ((dp = readdir(dirp)) != NULL) {
  683. X    cp = dp->d_name;
  684. X#ifdef FAKED_DIRECTORY
  685. X    if (dp->d_ino == 0) continue;
  686. X    cp[14] = NUL;
  687. X#endif
  688. X    if (*cp == '.' && (cp[1] == '\0' || (cp[1] == '.' && cp[2] == '\0')))
  689. X        continue;
  690. X    if (pflen && strncmp(prefix, cp, pflen)) continue;
  691. X    if (count == comp_length) {
  692. X        comp_length += 100;
  693. X        completions = resizeobj(completions, char *, comp_length + 1);
  694. X        comp = completions + count;
  695. X    }
  696. X    strcpy(*comp++ = alloc_str(strlen(cp)), cp);
  697. X    count++;
  698. X    }
  699. X    closedir(dirp);
  700. X    if (count == 0) {
  701. X    release_str(&str_mark);
  702. X    return 0;
  703. X    }
  704. X
  705. X    quicksort(completions, count, char *, sort_directory);
  706. X    *comp = (char *)0;
  707. X    comp_iterator = completions;
  708. X    comp_help = completions;
  709. X
  710. X    dir_tail = dir_path;
  711. X    while (*dir_tail++ = *dir++);
  712. X    dir_tail[-1] = '/';
  713. X
  714. X    return 1;
  715. X}
  716. X
  717. Xnext_directory(buffer, add_slash)
  718. Xregister char *buffer;
  719. Xint add_slash;
  720. X{
  721. X    if (*comp_iterator != NULL) {
  722. X    strcpy(buffer, *comp_iterator);
  723. X
  724. X    if (add_slash) {
  725. X        strcpy(dir_tail, *comp_iterator);
  726. X        if (file_exist(dir_path, "d"))
  727. X        strcat(buffer, "/");
  728. X    }
  729. X    comp_iterator++;
  730. X    return 1;
  731. X    }
  732. X    close_directory();
  733. X    return 0;
  734. X}
  735. X
  736. Xcompl_help_directory()
  737. X{
  738. X    list_completion((char *)NULL);
  739. X
  740. X    if (*comp_help == NULL) comp_help = completions;
  741. X    while (*comp_help && list_completion(*comp_help))
  742. X        comp_help++;
  743. X
  744. X    fl;
  745. X    return 1;
  746. X}
  747. X
  748. Xclose_directory()
  749. X{
  750. X    if (completions) {
  751. X    release_str(&str_mark);
  752. X    freeobj(completions);
  753. X    completions = NULL;
  754. X    }
  755. X}
  756. X
  757. X#else
  758. X
  759. Xstatic FILE *dirf;
  760. Xstatic int prefix_lgt;
  761. X
  762. Xlist_directory(dir, prefix)
  763. Xchar *dir, *prefix;
  764. X{
  765. X    if (prefix[0])
  766. X    sprintf(dir_path, "cd %s && echo %s* 2>/dev/null", dir, prefix);
  767. X    else
  768. X    sprintf(dir_path, "cd %s && ls 2>/dev/null", dir);
  769. X    prefix_lgt = strlen(prefix);
  770. X
  771. X    if ((dirf = popen(dir_path, "r")) == NULL) return 0;
  772. X
  773. X    dir_tail = dir_path;
  774. X    while (*dir_tail++ = *dir++);
  775. X    dir_tail[-1] = '/';
  776. X
  777. X    return 1;
  778. X}
  779. X
  780. Xnext_directory(buffer, add_slash)
  781. Xchar *buffer;
  782. Xint add_slash;
  783. X{
  784. X    register char *cp;
  785. X    register int c;
  786. X
  787. X    cp = buffer;
  788. X    while ((c = getc(dirf)) != EOF && (c != SP) && (c != NL))
  789. X    *cp++ = c;
  790. X
  791. X    if (cp != buffer) {
  792. X    *cp = NUL;
  793. X    if (strcmp(buffer + prefix_lgt, "*")) {
  794. X
  795. X        if (!add_slash) return 1;
  796. X
  797. X        strcpy(dir_tail, buffer);
  798. X            if (file_exist(dir_path, "d")) {
  799. X        *cp++ = '/';
  800. X        *cp = NUL;
  801. X        }
  802. X
  803. X        return 1;
  804. X    }
  805. X
  806. X    }
  807. X
  808. X    close_directory();
  809. X    return 0;
  810. X}
  811. X
  812. Xcompl_help_directory()
  813. X{
  814. X    return 0;
  815. X}
  816. X
  817. Xclose_directory()
  818. X{
  819. X    if (dirf) {
  820. X    pclose(dirf);
  821. X    dirf = NULL;
  822. X    }
  823. X}
  824. X#endif /* HAVE_DIRECTORY */
  825. X
  826. END_OF_FILE
  827.   if test 3623 -ne `wc -c <'dir.c'`; then
  828.     echo shar: \"'dir.c'\" unpacked with wrong size!
  829.   fi
  830.   # end of 'dir.c'
  831. fi
  832. if test -f 'execute.c' -a "${1}" != "-c" ; then 
  833.   echo shar: Will not clobber existing file \"'execute.c'\"
  834. else
  835.   echo shar: Extracting \"'execute.c'\" \(3113 characters\)
  836.   sed "s/^X//" >'execute.c' <<'END_OF_FILE'
  837. X/*
  838. X *    (c) Copyright 1990, Kim Fabricius Storm.  All rights reserved.
  839. X *
  840. X *    UNIX command execution.
  841. X */
  842. X
  843. X#include <signal.h>
  844. X#include <errno.h>
  845. X#include "config.h"
  846. X#include "term.h"
  847. X
  848. Xexport int shell_restrictions = 0;    /* disable shell escapes */
  849. X
  850. Xexport char *user_shell;
  851. Xexport char *exec_chdir_to = NULL;
  852. X
  853. Xstatic shell_check()
  854. X{
  855. X    if (shell_restrictions) {
  856. X    msg("Restricted operation - not allowed");
  857. X    return -1;
  858. X    }
  859. X    return 0;
  860. X}
  861. X
  862. X
  863. Xinit_execute()
  864. X{
  865. X    if ((user_shell = getenv("SHELL")) == NULL)
  866. X    user_shell = SHELL;
  867. X}
  868. X
  869. Xexecute(path, args, toggle_visual)
  870. Xchar *path, **args;
  871. Xint toggle_visual;
  872. X{
  873. X    int was_raw, pid, i, status;
  874. X    sig_type  (*quit)(), (*intr)(), (*tstp)();
  875. X    extern int errno;
  876. X
  877. X    was_raw = toggle_visual ? visual_off() : unset_raw();
  878. X
  879. X    while ((pid = fork()) == -1) sleep(1);
  880. X
  881. X    if (pid == 0) {
  882. X    for (i = 3 ; i < 20 ; i++)
  883. X        close(i);
  884. X
  885. X    if (exec_chdir_to != NULL) chdir(exec_chdir_to);
  886. X
  887. X    execv(path, args);
  888. X
  889. X    fprintf(stderr, "%s: not found\n", path);
  890. X    nn_exit(20);
  891. X    }
  892. X    quit = signal(SIGQUIT, SIG_IGN);
  893. X    intr = signal(SIGINT,  SIG_IGN);
  894. X#ifdef HAVE_JOBCONTROL
  895. X    tstp = signal(SIGTSTP, SIG_DFL);
  896. X#endif
  897. X    while ((i = wait(&status)) != pid && (i != -1 || errno == EINTR));
  898. X
  899. X    signal(SIGQUIT, quit);
  900. X    signal(SIGINT,  intr);
  901. X#ifdef HAVE_JOBCONTROL
  902. X    signal(SIGTSTP, tstp);
  903. X#endif
  904. X    if (toggle_visual) {
  905. X    visual_on();
  906. X    if (toggle_visual == 2) s_redraw++;
  907. X    }
  908. X
  909. X    if (was_raw) raw();
  910. X
  911. X    return status != 0;
  912. X}
  913. X
  914. X
  915. Xshell_escape()
  916. X{
  917. X    static char command[FILENAME] = "";
  918. X    char *cmd;
  919. X    int first = 1;
  920. X
  921. X    if (shell_check()) return 0;
  922. X
  923. X    for (;;) {
  924. X    prompt("\1!\1");
  925. X    cmd = get_s(command, NONE, NONE, NULL_FCT);
  926. X    if (cmd == NULL) return !first;
  927. X
  928. X    if (*cmd == NUL) {
  929. X        if (first) run_shell((char *)NULL, 1);
  930. X        return 1;
  931. X    }
  932. X
  933. X    strcpy(command, cmd);
  934. X
  935. X    if (!run_shell(command, first)) return !first;
  936. X    first = 0;
  937. X    prompt_line = -1;
  938. X    }
  939. X}
  940. X
  941. X
  942. Xstatic char *exec_sh_args[] = {
  943. X    "nnsh",
  944. X    (char *)NULL, /* "-c" or "-i" */
  945. X    (char *)NULL, /* cmdstring */
  946. X    (char *)NULL
  947. X};
  948. X
  949. Xrun_shell(command, clear)
  950. Xchar *command;
  951. Xint clear; /* -2 => no command output (:!!command) - keep visual,
  952. X          output before command: -1 => none, 0 => CR/NL, 1 => clear */
  953. X{
  954. X    char cmdstring[512];
  955. X
  956. X    if (shell_check()) return 0;
  957. X
  958. X    if (command != NULL) {
  959. X    if (!expand_file_name(cmdstring, command, 1)) return 0;
  960. X    exec_sh_args[1] = "-c";
  961. X        exec_sh_args[2] = cmdstring;
  962. X    } else {
  963. X    exec_sh_args[1] = "-i";
  964. X        exec_sh_args[2] = NULL;
  965. X    }
  966. X
  967. X    if (clear > 0) {
  968. X    clrdisp();
  969. X    fl;
  970. X    } else if (clear == 0) {
  971. X    putchar(CR);
  972. X    putchar(NL);
  973. X    }
  974. X
  975. X    execute(user_shell, exec_sh_args, clear == -2 ? 0 : 1);
  976. X    return 1;
  977. X}
  978. X
  979. X#ifndef HAVE_JOBCONTROL
  980. Xstatic char *exec_suspend_args[] = {
  981. X    "nnsh",
  982. X    "-i",
  983. X    (char *)NULL
  984. X};
  985. X#endif
  986. X
  987. Xsuspend_nn()
  988. X{
  989. X    int was_raw;
  990. X
  991. X    if (shell_check()) return 0;
  992. X
  993. X    gotoxy(0, Lines-1);
  994. X    clrline();
  995. X
  996. X#ifdef HAVE_JOBCONTROL
  997. X    was_raw = visual_off();
  998. X    kill(process_id, SIGSTOP);
  999. X    visual_on();
  1000. X    s_redraw++;
  1001. X    if (was_raw) raw();
  1002. X#else
  1003. X    execute(user_shell, exec_suspend_args, 2);
  1004. X#endif
  1005. X
  1006. X    return 1;
  1007. X}
  1008. END_OF_FILE
  1009.   if test 3113 -ne `wc -c <'execute.c'`; then
  1010.     echo shar: \"'execute.c'\" unpacked with wrong size!
  1011.   fi
  1012.   # end of 'execute.c'
  1013. fi
  1014. if test -f 'global.h' -a "${1}" != "-c" ; then 
  1015.   echo shar: Will not clobber existing file \"'global.h'\"
  1016. else
  1017.   echo shar: Extracting \"'global.h'\" \(4559 characters\)
  1018.   sed "s/^X//" >'global.h' <<'END_OF_FILE'
  1019. X/*
  1020. X *    (c) Copyright 1990, Kim Fabricius Storm.  All rights reserved.
  1021. X *
  1022. X *    Global declarations and definitions.
  1023. X */
  1024. X
  1025. X/*
  1026. X *    Marks for global/external variables
  1027. X */
  1028. X
  1029. X#define    export            /* export variable from module */
  1030. X#define import    extern        /* import variable into module */
  1031. X
  1032. X/*
  1033. X *    Various constants and types
  1034. X */
  1035. X
  1036. Xtypedef int8      attr_type;
  1037. Xtypedef int32     flag_type;
  1038. X
  1039. X#ifdef I286_BUG
  1040. X#    define FLAG(n)    (1L<<(n-1))
  1041. X#else
  1042. X#    define FLAG(n)    (((flag_type)1)<<(n-1))
  1043. X#endif
  1044. X
  1045. Xtypedef int32    article_number;
  1046. Xtypedef int16    group_number;
  1047. Xtypedef uint32    time_stamp;
  1048. X
  1049. Xtypedef int    (* fct_type )();
  1050. X#define CALL(fct)  (* (fct))
  1051. X#define NULL_FCT  (fct_type)NULL
  1052. X
  1053. X/* frequently used characters */
  1054. X
  1055. X#define NUL    '\0'
  1056. X#define TAB    '\t'
  1057. X#define NL    '\n'
  1058. X#define CR    '\r'
  1059. X#define BS    '\b'
  1060. X#define SP    ' '
  1061. X
  1062. X/* misc macros */
  1063. X
  1064. X#define fl fflush(stdout)
  1065. X
  1066. X#ifdef CONTROL_
  1067. X#undef CONTROL_
  1068. X#endif
  1069. X#define CONTROL_(c)    (c&037)
  1070. X
  1071. X#ifndef HAVE_STRCHR
  1072. X#define    strrchr        rindex
  1073. X#define strchr        index
  1074. X#endif
  1075. X
  1076. X#ifdef SIGNAL_HANDLERS_ARE_VOID
  1077. X#define sig_type void
  1078. X#else
  1079. X#define sig_type int
  1080. X#endif
  1081. X
  1082. X#ifndef NNTP
  1083. X#undef NNTP_POST
  1084. X#endif
  1085. X
  1086. X/*
  1087. X *    Some systems don't define these in <sys/stat.h>
  1088. X */
  1089. X
  1090. X#ifndef S_IFMT
  1091. X#define    S_IFMT    0170000            /* type of file */
  1092. X#define S_IFDIR    0040000            /* directory */
  1093. X#define S_IFREG    0100000            /* regular */
  1094. X#endif
  1095. X
  1096. X#ifndef O_RDONLY
  1097. X#define    O_RDONLY    0
  1098. X#define    O_WRONLY    1
  1099. X#define    O_RDWR        2
  1100. X#endif
  1101. X
  1102. X/* define types of library functions */
  1103. X
  1104. Xchar     *getenv(), *ctime();
  1105. Xchar     *strchr(), *strrchr();
  1106. Xoff_t     lseek(), ftell(), tell();
  1107. Xint    atoi();
  1108. Xlong    atol();
  1109. X
  1110. X
  1111. X/* define types of own functions */
  1112. X
  1113. Xchar *mk_file_name(), *home_relative();
  1114. Xchar *date_time(), *user_name(), *plural();
  1115. Xchar *copy_str();
  1116. X
  1117. Xtime_t    file_exist(), m_time(), cur_time();
  1118. X
  1119. Xextern FILE *open_file();
  1120. Xchar *relative();
  1121. X
  1122. X#define    OPEN_READ    0    /* open for reading */
  1123. X#define    OPEN_UPDATE    1    /* open/create for update */
  1124. X#define    OPEN_CREATE    2    /* create/truncate for write */
  1125. X#define    OPEN_APPEND    3    /* open for append */
  1126. X#define OPEN_CREATE_RW    4    /* create for read/write */
  1127. X
  1128. X#define    DONT_CREATE    0x40    /* return if file does not exist */
  1129. X#define    MUST_EXIST    0x80    /* fatal error if cannot open */
  1130. X#define    OPEN_UNLINK    0x100    /* unlink after open (not OPEN_UPDATE) */
  1131. X
  1132. X
  1133. X/*
  1134. X *    Other external definitions
  1135. X *
  1136. X *    NOTICE: the distinction between pointers and arrays is important
  1137. X *        here (they are global variables - not function arguments)
  1138. X */
  1139. X
  1140. Xextern char
  1141. X
  1142. X    *nn_directory,
  1143. X    *lib_directory,
  1144. X    version_id[];
  1145. X
  1146. X#ifdef NNTP
  1147. Xextern int  use_nntp;   /* 1 iff we are using nntp */
  1148. X#else
  1149. X#define use_nntp 0    /* for optimizers */
  1150. X#endif
  1151. X
  1152. Xextern int
  1153. X    s_hangup,    /* hangup signal */
  1154. X    s_keyboard,    /* keyboard signal */
  1155. X    s_pipe,    /* broken pipe */
  1156. X    s_redraw;    /* continue signal after stop */
  1157. X
  1158. Xextern int who_am_i;
  1159. X
  1160. X#define I_AM_MASTER    0
  1161. X#define I_AM_NN        1
  1162. X#define I_AM_ADMIN    2
  1163. X#define I_AM_CHECK    3
  1164. X#define I_AM_TIDY    4
  1165. X#define I_AM_EMACS    5
  1166. X#define I_AM_GOBACK    6
  1167. X#define I_AM_POST    7
  1168. X#define I_AM_GREP    8
  1169. X#define    I_AM_DAILY    9
  1170. X#define    I_AM_SPEW    10
  1171. X#define I_AM_EXPIRE    11
  1172. X#define    I_AM_ACCT    12
  1173. X
  1174. Xextern unsigned short        /* as they are on most systems... */
  1175. X    user_id,
  1176. X    group_id;
  1177. X
  1178. Xextern int
  1179. X    process_id;
  1180. X
  1181. Xextern int errno;
  1182. X
  1183. X/*
  1184. X *    Storage management
  1185. X */
  1186. X
  1187. Xextern char *mem_obj(), *mem_resize(), *mem_str();
  1188. X
  1189. X#define    newobj(type, nelt) \
  1190. X    (type *)mem_obj(sizeof(type), (int32)(nelt))
  1191. X
  1192. X#define    newstr(nelt) \
  1193. X    mem_str((int32)(nelt))
  1194. X
  1195. X#define    resizeobj(obj, type, nelt) \
  1196. X    (type *)mem_resize((char *)(obj), sizeof(type), (int32)(nelt))
  1197. X
  1198. X#define    freeobj(obj) mem_free((char *)(obj))
  1199. X
  1200. X#define quicksort(a,n,t,f) qsort((char *)(a), (unsigned)(n), sizeof(t), f)
  1201. X
  1202. X#include "vararg.h"
  1203. X#include "data.h"
  1204. X
  1205. X/*
  1206. X *    db external data
  1207. X */
  1208. X
  1209. Xextern master_header master;
  1210. X
  1211. X/* group headers */
  1212. X
  1213. Xextern group_header *active_groups, **sorted_groups;
  1214. X
  1215. X/* current group information */
  1216. X
  1217. Xextern char     group_path_name[];
  1218. Xextern char    *group_file_name;
  1219. X
  1220. Xextern group_header *current_group, *group_sequence, *rc_sequence;
  1221. X
  1222. Xextern group_header *lookup();
  1223. X
  1224. X
  1225. Xint l_g_index, s_g_first;
  1226. X
  1227. X#define    Loop_Groups_Number(num) \
  1228. X    for (num = 0; num < master.number_of_groups; num++)
  1229. X
  1230. X#define Loop_Groups_Header(gh) \
  1231. X    for (l_g_index = 0, gh=active_groups; \
  1232. X     l_g_index < master.number_of_groups; \
  1233. X     l_g_index++, gh++)
  1234. X
  1235. X#define Loop_Groups_Sorted(gh) \
  1236. X    for (l_g_index = s_g_first; \
  1237. X     (l_g_index < master.number_of_groups) && \
  1238. X     (gh = sorted_groups[l_g_index]) ;\
  1239. X     l_g_index++)
  1240. X
  1241. X#define    Loop_Groups_Sequence(gh) \
  1242. X    for (gh = group_sequence; gh; gh = gh->next_group)
  1243. X
  1244. X#define    Loop_Groups_Newsrc(gh) \
  1245. X    for (gh = rc_sequence; gh; gh = gh->newsrc_seq)
  1246. END_OF_FILE
  1247.   if test 4559 -ne `wc -c <'global.h'`; then
  1248.     echo shar: \"'global.h'\" unpacked with wrong size!
  1249.   fi
  1250.   # end of 'global.h'
  1251. fi
  1252. if test -f 'inews/Makefile' -a "${1}" != "-c" ; then 
  1253.   echo shar: Will not clobber existing file \"'inews/Makefile'\"
  1254. else
  1255.   echo shar: Extracting \"'inews/Makefile'\" \(1463 characters\)
  1256.   sed "s/^X//" >'inews/Makefile' <<'END_OF_FILE'
  1257. X# Makefile for NN version of mini inews.
  1258. X#
  1259. X# $RCSfile: Makefile,v $    $Revision: 1.3 $
  1260. X#
  1261. X# $Author: news $    $Date: 89/12/21 17:59:52 $
  1262. X#
  1263. X# $State: Exp $    $Locker:  $
  1264. X#
  1265. X# $Log:    Makefile,v $
  1266. X# Revision 1.3  89/12/21  17:59:52  news
  1267. X# Added kit processing, cleanups.
  1268. X#
  1269. X
  1270. XTARGET    = inews
  1271. X
  1272. XBINDIR    = /usr/lib/news/
  1273. XSHELL    = /bin/sh
  1274. X
  1275. XCC    = cc
  1276. X# General definitions here which apply to all -- form -DDEF
  1277. XDEFS    = -DFOR_NN
  1278. X# Link libraries -- form -lLIB
  1279. XLIBS    = ../hostname.o
  1280. X# Lint definitions -- same as DEFS, but form -D DEF
  1281. XLDEFS    = -D lint -D FOR_NN
  1282. X# Lint libraries -- same as LIBS, but form -l LIB
  1283. XLLIBS    =
  1284. X# Set to -g for debugging, -O for optimise, or both if compiler handles it
  1285. XDEBUG    = -O
  1286. XCFLAGS    = $(DEBUG) $(DEFS) -I.. -I../conf
  1287. X
  1288. XSRCS    = inews.c clientlib.c version.c
  1289. XOBJS    = inews.o clientlib.o version.o
  1290. XCLUDES    = clientlib.h conf.h nntp.h
  1291. XKIT    = Makefile README README.NN $(SRCS) $(CLUDES)
  1292. X
  1293. X$(TARGET): $(OBJS)
  1294. X    $(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
  1295. X
  1296. X$(OBJS):    $(CLUDES)
  1297. X
  1298. Xall:    $(TARGET)
  1299. X
  1300. XManifest:    $(KIT)
  1301. X    touch Manifest
  1302. X    rm -f foo
  1303. X    ls -ls Manifest $(KIT) > foo
  1304. X    mv foo Manifest
  1305. X    ls -ls Manifest $(KIT) > foo
  1306. X    mv foo Manifest
  1307. X
  1308. Xkit:    Manifest
  1309. X    shar Manifest $(KIT) > inews.shar
  1310. X
  1311. Xclean:
  1312. X    rm -f $(OBJS) core lint tags
  1313. X
  1314. Xclobber:    clean
  1315. X    rm -f $(TARGET) Make.Log Manifest $(KIT)
  1316. X
  1317. Xlint:    $(SRCS)
  1318. X    lint -D lint $(LLIBES) $(LDEFS) $(SRCS) > lint
  1319. X
  1320. Xtags:    $(SRCS)
  1321. X    ctags $(SRCS)
  1322. X
  1323. Xinstall:    $(TARGET)
  1324. X    ../inst inews $(TARGET)
  1325. X#    install -o news -g news -m 511 -s -c $(TARGET) $(BINDIR)
  1326. END_OF_FILE
  1327.   if test 1463 -ne `wc -c <'inews/Makefile'`; then
  1328.     echo shar: \"'inews/Makefile'\" unpacked with wrong size!
  1329.   fi
  1330.   # end of 'inews/Makefile'
  1331. fi
  1332. if test -f 'inews/README.NN' -a "${1}" != "-c" ; then 
  1333.   echo shar: Will not clobber existing file \"'inews/README.NN'\"
  1334. else
  1335.   echo shar: Extracting \"'inews/README.NN'\" \(3051 characters\)
  1336.   sed "s/^X//" >'inews/README.NN' <<'END_OF_FILE'
  1337. XFrom: Steve Simmons <scs%itivax@relay.EU.net>
  1338. XTo: storm@texas.dk (Kim F. Storm)
  1339. XDate: Thu, 21 Dec 89 18:02:03 EDT
  1340. XSubject: Inews Kit For NN
  1341. X
  1342. XWhat Is This:
  1343. X
  1344. XThis is a mini-inews, suitable for building client-only versions of NN
  1345. Xthat use NNTP for remote reading.  Some unknown (to me) person patched
  1346. Xit to be driven on NNs config.h file.  I have taken those changes, reversed
  1347. Xmost of them and upgraded to NNTP release version 1.5.7.  This inews was
  1348. Xa co-operative venture when Stan released it, and it's kind of fitting
  1349. Xthat it continues to be worked on by many hands.
  1350. X
  1351. XIf you have a full installation of news where you're installing NN,
  1352. Xyou could care less about this.
  1353. X
  1354. XCopyrights:
  1355. X
  1356. XSee individual files for authors.  I wrote conf.h and the
  1357. XMakefile, and explicitly put them in the public domain.  Other parts
  1358. Xmay have other copyrights, see the individual files.
  1359. X
  1360. XMaintenance:
  1361. X
  1362. XMy less-than-humble opinion is that as Stan releases nntp patches, you will
  1363. Xbe able to apply them to this code with no changes whatsoever.  As Stan
  1364. Xreleases patches I will attempt to apply them and upgrade this source,
  1365. Xbut no guarantees.
  1366. X
  1367. XWhy A Separate Release From NNTP:
  1368. X
  1369. XNN and NNTP both use configuration files to let you fit the software
  1370. Xfor your system.  Unfortunately, they used rather different methods.
  1371. XThis release specificly reconciles NNs 'config.h' and NNTPs '../common/conf.h'
  1372. Xby creating a local "conf.h" which maps 'config.h' to what NNTP inews needs.
  1373. XResult -- once you build the config.h for NN you're 98% done with NNTP inews.
  1374. X
  1375. XINSTALLATION:
  1376. X
  1377. XIdeally you went to your nn source directory and created a subdir
  1378. Xnamed inews.  Then you unpacked this in that directory (I have already
  1379. Xdone that, ++Kim).
  1380. X
  1381. XAll you should need to do is read conf.h, make any changes you feel
  1382. Xlike, and then type 'make'.  If things work, type 'make install'.  For
  1383. Xmore data on the inews itself, read the file README.  It's slightly
  1384. Xedited from the NNTP version to reflect its separation from the rest
  1385. Xof NNTP.
  1386. X
  1387. XFor more data on the inews itself, read the file README.  It's
  1388. Xslightly edited from the NNTP version to reflect its separation from
  1389. Xthe rest of NNTP.
  1390. X
  1391. XSteve Simmons
  1392. Xscs@lokkur.dexter.mi.us
  1393. XDecember 21, 1989
  1394. X
  1395. X
  1396. X--- Changes by Kim Storm, storm@texas.dk
  1397. X
  1398. XI have edited what Steve sent me a bit further to simplify the
  1399. Xconfiguration and installation even more: It now uses nn's code to get
  1400. Xthe hostname, so this is now got for free, and it gets the location of
  1401. Xthe inews program from config.h as well.
  1402. X
  1403. XMakefile:
  1404. X    Added -I../conf to CFLAGS
  1405. X    nn's hostname.o is used instead of uname.o to get the hostname.
  1406. X    Installation uses nn's inst script (which will use the possible
  1407. X    definition of INEWS or NEWS_LIB_DIRECTORY in config.h).
  1408. X
  1409. Xconf.h:
  1410. X    #defines to set the proper hostname removed.
  1411. X    #include "../config.h" line moved to start of file.
  1412. X    Documents optional #define USG to get bcopy function.
  1413. X
  1414. Xclientlib.c, inews.c
  1415. X    Added tweaks using a FOR_NN #define to include/exclude
  1416. X    code to co-exist with nn's config.h file.
  1417. X
  1418. Xuname.c:
  1419. X    Not used (so it is omitted from this distribution).
  1420. END_OF_FILE
  1421.   if test 3051 -ne `wc -c <'inews/README.NN'`; then
  1422.     echo shar: \"'inews/README.NN'\" unpacked with wrong size!
  1423.   fi
  1424.   # end of 'inews/README.NN'
  1425. fi
  1426. if test -f 'keymap.h' -a "${1}" != "-c" ; then 
  1427.   echo shar: Will not clobber existing file \"'keymap.h'\"
  1428. else
  1429.   echo shar: Extracting \"'keymap.h'\" \(4642 characters\)
  1430.   sed "s/^X//" >'keymap.h' <<'END_OF_FILE'
  1431. X/*
  1432. X *    (c) Copyright 1990, Kim Fabricius Storm.  All rights reserved.
  1433. X *
  1434. X *    Keyboard (re)mapping
  1435. X */
  1436. X
  1437. X#define K_INVALID        0x0000 /* unknown command (for lookup) */
  1438. X
  1439. X#define K_UNBOUND        0x0001 /* unbound command key         */
  1440. X
  1441. X#define K_REDRAW        0x0002 /* redraw             */
  1442. X#define K_CONTINUE        0x0003 /* continue with next ...     */
  1443. X#define K_LAST_MESSAGE        0x0004 /* repeat last message         */
  1444. X#define K_HELP            0x0005 /* online help             */
  1445. X#define K_SHELL            0x0006 /* shell escape         */
  1446. X#define K_VERSION        0x0007 /* print version         */
  1447. X#define K_EXTENDED_CMD        0x0008 /* extended commands        */
  1448. X
  1449. X#define K_QUIT            0x0009 /* quit             */
  1450. X
  1451. X#define    K_BUG_REPORT        0x000a /* send bug report */
  1452. X
  1453. X#define K_SAVE_NO_HEADER     0x0011 /* save articles without header */
  1454. X#define K_SAVE_SHORT_HEADER     0x0012 /* save article with short header */
  1455. X#define K_SAVE_FULL_HEADER     0x0013 /* save articles with full header */
  1456. X
  1457. X#define K_PRINT            0x0014 /* print ariticle         */
  1458. X
  1459. X#define K_UNSHAR        0x0015 /* unshar article        */
  1460. X
  1461. X#define K_REPLY            0x0016 /* reply to article         */
  1462. X#define K_FOLLOW_UP        0x0017 /* follow up to article     */
  1463. X#define K_POST            0x0018 /* post an article        */
  1464. X#define K_MAIL_OR_FORWARD     0x0019 /* mail (forward article)     */
  1465. X#define K_CANCEL        0x001a /* cancel article         */
  1466. X#define K_UNSUBSCRIBE        0x001b /* (un)subscribe to group     */
  1467. X#define K_GROUP_OVERVIEW     0x001c /* group overview         */
  1468. X#define K_PATCH            0x001d /* pipe article to patch         */
  1469. X#define    K_UUDECODE        0x001e /* uudecode articles        */
  1470. X
  1471. X#define K_GOTO_GROUP        0x001f /* goto named group/folder    */
  1472. X
  1473. X#define K_KILL_HANDLING        0x0020 /* enter kill menu        */
  1474. X
  1475. X    /* scrolling/menu movement */
  1476. X
  1477. X#define K_CONTINUE_NO_MARK    0x0021 /* as continue but don't mark seen */
  1478. X#define K_JUNK_ARTICLES        0x0022 /* convert given attr to read    */
  1479. X#define K_SKIP_LINES        0x0023 /* skip lines of same type    */
  1480. X#define K_NEXT_PAGE        0x0024 /* next page             */
  1481. X#define K_NEXT_HALF_PAGE     0x0025 /* next half page        */
  1482. X#define K_NEXT_LINE        0x0026 /* next line            */
  1483. X#define K_PREV_PAGE        0x0027 /* previous page         */
  1484. X#define K_PREV_HALF_PAGE     0x0028 /* previous half page        */
  1485. X#define K_PREV_LINE        0x0029 /* previous line        */
  1486. X
  1487. X#define K_HEADER_PAGE        0x002a /* first page incl. header    */
  1488. X#define K_FIRST_PAGE        0x002b /* first page             */
  1489. X#define K_LAST_PAGE        0x002c /* last page             */
  1490. X
  1491. X#define K_GOTO_LINE        0x002d /* goto specific line        */
  1492. X#define K_GOTO_PAGE        0x002e /* goto specific page        */
  1493. X#define K_GOTO_MATCH        0x002f /* goto line matching regexp    */
  1494. X#define K_NEXT_MATCH        0x0030 /* find next match        */
  1495. X
  1496. X#define K_PREVIOUS        0x0031 /* goto prev group or article    */
  1497. X                /* (no update is performed)    */
  1498. X
  1499. X    /* more() SPECIFIC COMMANDS */
  1500. X
  1501. X#define K_LEAVE_ARTICLE        0x0032 /* goto next article, mark current */
  1502. X#define K_LEAVE_NEXT        0x0033 /* mark current for next time    */
  1503. X#define K_NEXT_ARTICLE        0x0034 /* goto next article         */
  1504. X#define K_NEXT_SUBJECT        0x0035 /* goto next subject        */
  1505. X#define K_FULL_DIGEST        0x0036 /* show full digest        */
  1506. X#define K_ROT13            0x0037 /* do rot13             */
  1507. X#define K_COMPRESS        0x0038 /* compress spaces        */
  1508. X#define K_BACK_TO_MENU        0x0039 /* return to menu */
  1509. X#define    K_BACK_ARTICLE        0x003a /* back one article        */
  1510. X#define    K_FORW_ARTICLE        0x003b /* forward one article        */
  1511. X
  1512. X    /* menu() SPECIFIC COMMANDS     */
  1513. X
  1514. X#define K_SELECT        0x0041 /* select current, move down     */
  1515. X#define K_SELECT_INVERT        0x0042 /* invert all selections     */
  1516. X#define K_SELECT_SUBJECT     0x0043 /* select all with same subject */
  1517. X#define K_SELECT_RANGE        0x0044 /* select range         */
  1518. X#define K_AUTO_SELECT        0x0045 /* auto select from kill file    */
  1519. X#define K_UNSELECT_ALL        0x0046 /* undo all selections        */
  1520. X
  1521. X#define K_LAYOUT        0x0049 /* change menu layout         */
  1522. X
  1523. X#define K_NEXT_GROUP_NO_UPDATE     0x004a /* goto next group, no update     */
  1524. X#define K_READ_GROUP_UPDATE     0x004b /* read selected, then next group */
  1525. X#define K_READ_GROUP_THEN_SAME    0x004c /* read selected, then same group */
  1526. X
  1527. X#define K_ADVANCE_GROUP        0x004d /* advance one group in sequence */
  1528. X#define K_BACK_GROUP        0x004e /* back-up one group in sequence */
  1529. X
  1530. X#define K_PREVIEW        0x004f /* preview article         */
  1531. X
  1532. X#define    K_EQUAL_KEY        0x0070 /* map command special symbol    */
  1533. X
  1534. X#define    K_MACRO            0x0100 /* call macro            */
  1535. X#define    K_ARTICLE_ID        0x0200 /* article id in lower part    */
  1536. X
  1537. X
  1538. X/*
  1539. X * KEY MAP SIZE is:
  1540. X *   (128 normal chars) + (0200) + (4 arrow keys) + (10 function keys)
  1541. X */
  1542. X
  1543. X#define MULTI_KEYS    (1 + 4 + 10)
  1544. X#define KEY_MAP_SIZE    (128 + MULTI_KEYS)
  1545. X
  1546. X
  1547. X/* restrictions */
  1548. X
  1549. X#define K_ONLY_MENU    0x0001
  1550. X#define K_ONLY_MORE    0x0002
  1551. X
  1552. Xtypedef unsigned char key_type;
  1553. X
  1554. Xextern int menu_key_map[];
  1555. Xextern int more_key_map[];
  1556. X
  1557. Xextern key_type global_key_map[];
  1558. X
  1559. Xextern char *key_name();
  1560. Xextern key_type parse_key();
  1561. END_OF_FILE
  1562.   if test 4642 -ne `wc -c <'keymap.h'`; then
  1563.     echo shar: \"'keymap.h'\" unpacked with wrong size!
  1564.   fi
  1565.   # end of 'keymap.h'
  1566. fi
  1567. if test -f 'man/nngoback.1' -a "${1}" != "-c" ; then 
  1568.   echo shar: Will not clobber existing file \"'man/nngoback.1'\"
  1569. else
  1570.   echo shar: Extracting \"'man/nngoback.1'\" \(3441 characters\)
  1571.   sed "s/^X//" >'man/nngoback.1' <<'END_OF_FILE'
  1572. X.TH NNGOBACK 1 "Release 6.4"
  1573. X.\" (c) Copyright 1988, 1990, Kim F. Storm.  All rights reserved.
  1574. X.UC 4
  1575. X.SH NAME
  1576. Xnngoback \- make news articles unread on a day-by-day basis (nn)
  1577. X.SH SYNOPSIS
  1578. X.B nngoback
  1579. X[ \-\fBNQvi\fP ]
  1580. X[\-\fBd\fP] \fIdays\fP
  1581. X[ \fIgroup\fP ]...
  1582. X.SH DESCRIPTION
  1583. X.I nngoback
  1584. Xwill rewind the .newsrc record file of \fBnn\fP(1) one or more \fIdays\fP.
  1585. XIt can be used to rewind all groups, or only a specified set of
  1586. X\fIgroups\fP.
  1587. XIn other words, \fInngoback\fP can mark news articles which have
  1588. Xarrived on the system during the last \fIdays\fP days unread.
  1589. X.LP
  1590. XOnly \fIsubscribed\fP groups that occur in the current presentation
  1591. Xsequence are rewound.  That means that if no \fIgroup\fP arguments are
  1592. Xspecified, all groups occurring in the sequence defined in the
  1593. X\fIinit\fP file will be rewound.  Otherwise, only the groups specified
  1594. Xon the argument line will be rewound.
  1595. X.LP
  1596. XWhen a group is rewound, the information about selections, partially
  1597. Xread digests etc. are discarded.  It will print notifications about
  1598. Xthis unless the \-\fBQ\fP (quiet) option is used.
  1599. X.LP
  1600. XIf the \-\fBi\fP (interactive) option is specified, \fInngoback\fP
  1601. Xwill report for each how many articles \fIcan be\fP marked unread, and
  1602. Xask for confirmation before going back in that group.
  1603. X.LP
  1604. XIf the \-\fBv\fP (verbose) option is specified, \fInngoback\fP will
  1605. Xreport how many articles are marked unread.
  1606. X.LP
  1607. XIf the \-\fBN\fP (no-update) option is specified, \fInngoback\fP will
  1608. Xperform the entire goback operation, but not update the .newsrc file.
  1609. X.LP
  1610. XIf you are not up-to-date with your news reading, you can also use
  1611. X\fBnngoback\fP to catch up to only have the last few days of news
  1612. Xwaiting to be read in the following way:
  1613. X.br
  1614. X    nn \-a0
  1615. X.br
  1616. X    nngoback 3
  1617. X.br
  1618. XThe \fBnn\fP command will mark all articles in all groups as read (answer
  1619. X.I all
  1620. Xto the catch-up question.)  The following \fBnngoback\fP will then make
  1621. Xthe last three days of news unread again.
  1622. X.LP
  1623. XExamples:
  1624. X.TP
  1625. Xnngoback 0
  1626. XMark the articles which have arrived today as unread.
  1627. X.TP
  1628. Xnngoback 1
  1629. XMark the articles which have arrived yesterday and today as unread.
  1630. X.TP
  1631. Xnngoback 6
  1632. XMark the articles which have arrived during the last week as unread.
  1633. X.LP
  1634. XYou cannot go more than 14 days back with \fInngoback\fP.
  1635. X.SH THE BACK_ACT DAEMON
  1636. XIt is a prerequisite for the use of \fInngoback\fP that the script
  1637. X\fBback_act\fP is executed at an appropriate time once (and only once)
  1638. Xevery day.  Preferably this is done by \fBcron\fP right before the
  1639. Xbacth of news for `today' is received.  \fBback_act\fP will maintain
  1640. Xcopies of the active file for the last 14 days.
  1641. X.SH FILES
  1642. X.DT
  1643. X.ta \w'~/.newsrc.goback'u+5m
  1644. X.\"ta 0 21
  1645. X~/.newsrc    The record of read articles.
  1646. X.br
  1647. X~/.newsrc.goback    The original rc file before goback.
  1648. X.br
  1649. X$db/active.\fIN\fP    The \fIN\fP days `old' active file.
  1650. X.br
  1651. X$master/back_act    Script run by cron to maintain old active files.
  1652. X.br
  1653. X.DT
  1654. X.SH SEE ALSO
  1655. Xnn(1), nncheck(1), nngrep(1), nntidy(1)
  1656. X.br
  1657. Xnnadmin(1M), nnquery(1M), nnusage(1M), nnmaster(8)
  1658. X.SH NOTES
  1659. X\fBnngoback\fP does not check the age of the `old' active files; it
  1660. Xwill blindly believe that active.0 was created today, and that
  1661. Xactive.7 is really seven days old!  Therefore, the \fIback_act\fP
  1662. Xscript should be run once and only once every day for \fInngoback\fP
  1663. Xto work properly.
  1664. X.LP
  1665. XThe days are counted relative to the time the active files were copied.
  1666. X.SH AUTHOR
  1667. XKim F. Storm, Texas Instruments A/S, Denmark
  1668. X.br
  1669. XE-mail: storm@texas.dk
  1670. END_OF_FILE
  1671.   if test 3441 -ne `wc -c <'man/nngoback.1'`; then
  1672.     echo shar: \"'man/nngoback.1'\" unpacked with wrong size!
  1673.   fi
  1674.   # end of 'man/nngoback.1'
  1675. fi
  1676. if test -f 'options.c' -a "${1}" != "-c" ; then 
  1677.   echo shar: Will not clobber existing file \"'options.c'\"
  1678. else
  1679.   echo shar: Extracting \"'options.c'\" \(3764 characters\)
  1680.   sed "s/^X//" >'options.c' <<'END_OF_FILE'
  1681. X/*
  1682. X *    (c) Copyright 1990, Kim Fabricius Storm.  All rights reserved.
  1683. X *
  1684. X *    Generic option parsing
  1685. X */
  1686. X
  1687. X#include "config.h"
  1688. X#include "options.h"
  1689. X
  1690. Xstatic char **save_argv, *usage_mesg;
  1691. Xstatic struct option_descr *save_optd;
  1692. X
  1693. X
  1694. Xchar *program_name(av)
  1695. Xchar **av;
  1696. X{
  1697. X    char *cp;
  1698. X
  1699. X    /* skip "/path/" part of program name */
  1700. X    if (cp = strrchr(*av, '/'))
  1701. X    return cp + 1;
  1702. X    else
  1703. X    return *av;
  1704. X}
  1705. X
  1706. Xstatic dump_options(type, tail)
  1707. Xint type;
  1708. Xchar *tail;
  1709. X{
  1710. X    register struct option_descr *od;
  1711. X    int any = 0;
  1712. X
  1713. X    for (od = save_optd; od->option_letter; od++) {
  1714. X    if (od->option_type != type) continue;
  1715. X    fprintf(stderr, any ? "%c" : " -%c", od->option_letter );
  1716. X    any++;
  1717. X    }
  1718. X
  1719. X    if (any && tail && tail[0]) {
  1720. X    fprintf(stderr, "%s", tail);
  1721. X    }
  1722. X}
  1723. X
  1724. Xstatic error(message, option_letter)
  1725. Xchar *message, option_letter;
  1726. X{
  1727. X    char *prog_name = program_name(save_argv);
  1728. X
  1729. X    fprintf(stderr, "%s: ", prog_name);
  1730. X    fprintf(stderr, message, option_letter);
  1731. X    fputc('\n', stderr);
  1732. X
  1733. X    fprintf(stderr, "usage: %s", prog_name);
  1734. X
  1735. X    dump_options(1, "");
  1736. X    dump_options(2, " STR");
  1737. X    dump_options(3, " [STR]");
  1738. X    dump_options(4, " NUM");
  1739. X    dump_options(5, " [NUM]");
  1740. X
  1741. X    if (usage_mesg) fprintf(stderr, usage_mesg);
  1742. X    fputc(NL, stderr);
  1743. X
  1744. X    nn_exit(9);
  1745. X}
  1746. X
  1747. Xparse_options(ac, av, envname, options, usage)
  1748. Xint ac;
  1749. Xchar **av, *envname;
  1750. Xstruct option_descr options[];
  1751. Xchar *usage;
  1752. X{
  1753. X    register char *cp, opt;
  1754. X    register struct option_descr *od;
  1755. X    extern int atoi();
  1756. X    int files;
  1757. X    char **names;
  1758. X    char *envinit;
  1759. X
  1760. X    save_argv = av;
  1761. X    save_optd = options;
  1762. X
  1763. X    if (options == NULL) return 0;
  1764. X
  1765. X    usage_mesg = usage;
  1766. X
  1767. X    --ac;
  1768. X    names = ++av;
  1769. X    files = 0;
  1770. X
  1771. X    envinit = envname ? getenv(envname) : NULL;
  1772. X    cp = envinit;
  1773. X
  1774. X next_option:
  1775. X
  1776. X    if (envinit) {
  1777. X    while (*cp && isspace(*cp)) cp++;
  1778. X    if (*cp == '-') {
  1779. X        cp++;
  1780. X        goto next_option;
  1781. X    }
  1782. X    if (*cp == NUL) {
  1783. X        envinit = NULL;
  1784. X        goto next_option;
  1785. X    }
  1786. X    } else
  1787. X    if (cp == NULL || *cp == NUL) {
  1788. X        if ((cp = *av++) == NULL) {
  1789. X        *names = NULL;
  1790. X        return files;
  1791. X        }
  1792. X        ac--;
  1793. X
  1794. X        if (*cp != '-') {
  1795. X        *names++ = cp;
  1796. X        cp = NULL;
  1797. X        files++;
  1798. X        goto next_option;
  1799. X        }
  1800. X
  1801. X        cp++; /* skip - */
  1802. X    }
  1803. X
  1804. X    opt = *cp++;
  1805. X
  1806. X    for (od = options; od->option_letter; od++) {
  1807. X    if (od->option_letter != opt) continue;
  1808. X
  1809. X    switch (od->option_type) {
  1810. X
  1811. X     case 1:    /* BOOL_OPTION */
  1812. X
  1813. X        *((int *)(od->option_address)) = !*((int *)(od->option_address));
  1814. X        goto next_option;
  1815. X
  1816. X     case 2:    /* STRING_OPTION */
  1817. X     case 3:    /* OPTIONAL_STRING */
  1818. X
  1819. X        /* -oSTR or -o STR */
  1820. X
  1821. X        while (*cp && isspace(*cp)) cp++;
  1822. X
  1823. X        if (*cp == NUL) {
  1824. X        if (envinit || ac == 0) {
  1825. X            if (od->option_type == 3) goto opt_str;
  1826. X            error("missing string argumet to -%c", opt);
  1827. X        }
  1828. X        cp = *av++;
  1829. X        ac--;
  1830. X        }
  1831. X
  1832. X        if (od->option_type == 3 && *cp == '-') {
  1833. X        cp++;
  1834. X        goto opt_str;
  1835. X        }
  1836. X
  1837. X        *(od->option_address) = cp;
  1838. X
  1839. X        if (envinit) {
  1840. X        while (*cp && !isspace(*cp)) cp++;
  1841. X        if (*cp) *cp++ = NUL;
  1842. X        } else
  1843. X        cp = NULL;
  1844. X
  1845. X        goto next_option;
  1846. X
  1847. X     opt_str:
  1848. X        *(od->option_address) = od->option_default;
  1849. X        goto next_option;
  1850. X
  1851. X     case 4:
  1852. X     case 5:
  1853. X
  1854. X        /* -oN or -o N */
  1855. X
  1856. X        while (*cp && isspace(*cp)) cp++;
  1857. X
  1858. X        if (*cp) {
  1859. X        if (!isdigit(*cp)) {
  1860. X            if (od->option_type == 5) goto opt_int;
  1861. X            error("non-numeric argument to -%c", opt);
  1862. X        }
  1863. X        } else {
  1864. X        if (envinit || ac == 0 || !isdigit(**av)) {
  1865. X            if (od->option_type == 5) goto opt_int;
  1866. X            error("missing argument to -%c", opt);
  1867. X        }
  1868. X
  1869. X        cp = *av++;
  1870. X        ac--;
  1871. X        }
  1872. X        *((int *)(od->option_address)) = atoi(cp);
  1873. X        while (isdigit(*cp)) cp++;
  1874. X        goto next_option;
  1875. X
  1876. X     opt_int:
  1877. X        *((int *)(od->option_address)) = (int)(od->option_default);
  1878. X        goto next_option;
  1879. X    }
  1880. X    }
  1881. X
  1882. X    error("unknown option '-%c'", opt);
  1883. X    /*NOTREACHED*/
  1884. X}
  1885. END_OF_FILE
  1886.   if test 3764 -ne `wc -c <'options.c'`; then
  1887.     echo shar: \"'options.c'\" unpacked with wrong size!
  1888.   fi
  1889.   # end of 'options.c'
  1890. fi
  1891. if test -f 'pack_date.c' -a "${1}" != "-c" ; then 
  1892.   echo shar: Will not clobber existing file \"'pack_date.c'\"
  1893. else
  1894.   echo shar: Extracting \"'pack_date.c'\" \(4124 characters\)
  1895.   sed "s/^X//" >'pack_date.c' <<'END_OF_FILE'
  1896. X/*
  1897. X *    (c) Copyright 1990, Kim Fabricius Storm.  All rights reserved.
  1898. X *
  1899. X *    Calculate an approximate "time_stamp" value for a date
  1900. X *    string.  The actual value is not at all critical,
  1901. X *    as long as the "ordering" is ok.
  1902. X *
  1903. X *    The result is NOT a time_t value, i.e. ctime() will
  1904. X *    not produce the original Date string.
  1905. X *
  1906. X *    The date must have format:  [...,] [D]D Mmm YY hh:mm:ss TZONE
  1907. X *
  1908. X *    Thanks to Wayne Davison for the timezone decoding code.
  1909. X */
  1910. X
  1911. X#include "config.h"
  1912. X
  1913. X/* #define DATE_TEST /* never define this !! */
  1914. X
  1915. Xstatic long wtz(h, m, c)
  1916. Xint  h, m;
  1917. Xchar c;
  1918. X{
  1919. X    if (c != 's') h--;        /* daylight savings */
  1920. X    return h*60L+m*30L;
  1921. X}
  1922. X
  1923. Xstatic long etz(h, m, c)
  1924. Xint  h, m;
  1925. Xchar c;
  1926. X{
  1927. X    if (c == 's') h++;        /* summer time */
  1928. X    return -(h*60L+m*30L);
  1929. X}
  1930. X
  1931. X#define TOLOWER(ch) (isupper(ch) ? tolower(ch) : (ch))
  1932. X
  1933. Xstatic long tzone(date)
  1934. Xregister char *date;
  1935. X{
  1936. X    char ch1, ch2, ch3, ch4;
  1937. X    long tz, wtz(), etz();
  1938. X
  1939. X    while (*date && !isalpha(*date)) date++;
  1940. X    if (*date == NUL || *date == 'G') return 0;
  1941. X
  1942. X    ch1 = TOLOWER(*date);
  1943. X    while (date++, (ch2 = TOLOWER(*date)) == '.')    /* p.s.t. -> pst */
  1944. X    ;
  1945. X    while (date++, (ch3 = TOLOWER(*date)) == '.')
  1946. X    ;
  1947. X    while (date++, (ch4 = TOLOWER(*date)) == '.')
  1948. X    ;
  1949. X    switch (ch1) {
  1950. X     case 'n':
  1951. X    tz = wtz(3,1,0); break;        /* Newfoundland: nst */
  1952. X     case 'a':
  1953. X    if (ch2 == 'e') {
  1954. X        tz = etz(10,0,ch4); break;    /* Australian Eastern: aest, aesst */
  1955. X    }
  1956. X    if (ch2 == 'c') {
  1957. X        tz = etz(9,1,ch4); break;    /* Australian Central: acst, acsst */
  1958. X    }
  1959. X    if (ch2 == 'w') {
  1960. X        tz = etz(8,1,ch4); break;    /* Australian Western: awst, awsst */
  1961. X    }
  1962. X    tz = wtz(4,0,ch2); break;    /* Atlantic: ast, adt */
  1963. X     case 'b':
  1964. X    tz = etz(1,0,0); break;        /* British summer: bst */
  1965. X     case 'c':
  1966. X    tz = wtz(6,0,ch2); break;    /* Central: cst, cdt */
  1967. X     case 'e':
  1968. X    if (ch2 == 'e') {
  1969. X        tz = etz(0,0,ch3); break;    /* European Eastern: eet, eest */
  1970. X    }
  1971. X    tz = wtz(5,0,ch2); break;    /* Eastern: est, edt */
  1972. X     case 'g':
  1973. X    tz = etz(0,0,0); break;        /* Greenwich: gmt */
  1974. X     case 'h':
  1975. X    tz = wtz(10,0,ch2); break;    /* Hawaii: hst, hdt */
  1976. X     case 'j':
  1977. X    tz = etz(9,0,0); break;        /* Japan: jst */
  1978. X     case 'm':
  1979. X    if (ch2 == 'e') {
  1980. X        tz = etz(1,0,ch3); break;    /* Middle European: met, mest */
  1981. X    }
  1982. X    tz = wtz(7,0,ch2); break;    /* Mountain: mst, mdt */
  1983. X     case 'p':
  1984. X    tz = wtz(8,0,ch2); break;    /* Pacific: pst, pdt */
  1985. X     case 'w':
  1986. X    tz = etz(2,0,ch3); break;    /* Western European: wet, west */
  1987. X     case 'y':
  1988. X    tz = wtz(9,0,ch2); break;    /* Yukon: yst, ydt */
  1989. X     default:
  1990. X    tz = 0; break;        /* use GMT if we can't understand it */
  1991. X    }
  1992. X
  1993. X    return tz;
  1994. X}
  1995. X
  1996. Xstatic next_int(dp)
  1997. Xchar **dp;
  1998. X{
  1999. X    register char *str = *dp;
  2000. X    register i;
  2001. X
  2002. X    while (*str && !isdigit(*str)) str++;
  2003. X
  2004. X    i = 0;
  2005. X    while (*str && isdigit(*str))
  2006. X    i = (i * 10) + *str++ - '0';
  2007. X
  2008. X    *dp = str;
  2009. X    return i;
  2010. X}
  2011. X
  2012. Xtime_stamp pack_date(date)
  2013. Xchar *date;
  2014. X{
  2015. X    register time_stamp res;
  2016. X    register int min, hour, day, mon, year;
  2017. X
  2018. X    if (date == NULL || (day = next_int(&date)) == 0) return 0;
  2019. X
  2020. X    while (*date && isspace(*date)) date++;
  2021. X
  2022. X    switch (*date++) {
  2023. X     case 'J':
  2024. X    if (*date++ == 'a') { mon = 0; break; }
  2025. X    if (*date++ == 'n') { mon = 5; break; }
  2026. X    mon = 6; break;
  2027. X     case 'F':
  2028. X    mon = 1; break;
  2029. X     case 'M':
  2030. X    if (*++date == 'r') { mon = 2; break; }
  2031. X    mon = 4; break;
  2032. X     case 'A':
  2033. X    if (*date++ == 'p') { mon = 3; break; }
  2034. X    mon = 7; break;
  2035. X     case 'S':
  2036. X    mon = 8; break;
  2037. X     case 'O':
  2038. X    mon = 9; break;
  2039. X     case 'N':
  2040. X    mon = 10; break;
  2041. X     case 'D':
  2042. X    mon = 11; break;
  2043. X     default:
  2044. X    return 0;
  2045. X    }
  2046. X
  2047. X    year = next_int(&date);
  2048. X    hour = next_int(&date);
  2049. X    min = next_int(&date);
  2050. X
  2051. X    year -= 87;    /* base is 1987 */
  2052. X    if (year < 0) year += 100;
  2053. X
  2054. X    res = (year * 12 + mon) * 31 + day - 1;
  2055. X    res *= 24 * 60;
  2056. X    res += (hour * 60) + min;
  2057. X
  2058. X    return res + tzone(date);
  2059. X}
  2060. X
  2061. X
  2062. X#ifdef DATE_TEST
  2063. X
  2064. X
  2065. Xmain()
  2066. X{
  2067. X    char buffer[128];
  2068. X    char *dp;
  2069. X    unsigned long t;
  2070. X
  2071. X    while (fgets(buffer, 128, stdin)) {
  2072. X    if (strncmp(buffer, "Date:", 5)) continue;
  2073. X
  2074. X    dp = strchr(buffer, ':');
  2075. X    if (dp == NULL) continue;
  2076. X    dp++;
  2077. X    while (isspace(*dp)) dp++;
  2078. X    t = pack_date(dp);
  2079. X    printf("%lu\t%s\n", t, dp);
  2080. X    }
  2081. X
  2082. X    exit(0);
  2083. X}
  2084. X
  2085. X#endif
  2086. END_OF_FILE
  2087.   if test 4124 -ne `wc -c <'pack_date.c'`; then
  2088.     echo shar: \"'pack_date.c'\" unpacked with wrong size!
  2089.   fi
  2090.   # end of 'pack_date.c'
  2091. fi
  2092. if test -f 'proto.c' -a "${1}" != "-c" ; then 
  2093.   echo shar: Will not clobber existing file \"'proto.c'\"
  2094. else
  2095.   echo shar: Extracting \"'proto.c'\" \(3702 characters\)
  2096.   sed "s/^X//" >'proto.c' <<'END_OF_FILE'
  2097. X/*
  2098. X *    (c) Copyright 1990, Kim Fabricius Storm.  All rights reserved.
  2099. X *
  2100. X *    Master/slave communication and locking.
  2101. X */
  2102. X
  2103. X#include "config.h"
  2104. X#include <signal.h>
  2105. X#include <errno.h>
  2106. X#include <pwd.h>
  2107. X#include "proto.h"
  2108. X
  2109. Ximport char *master_directory, *db_directory;
  2110. X
  2111. X/*
  2112. X *    When setting a lock, we must check a little later that
  2113. X *    we really got the lock set, i.e. that another process
  2114. X *    didn't set it at the same time!
  2115. X */
  2116. X
  2117. X#define LOCK_SAFETY    5    /* seconds */
  2118. X
  2119. X/*
  2120. X *    proto_lock(program, mode)
  2121. X *
  2122. X *    Returns:
  2123. X *    -1    Not running.
  2124. X *    0    Running, no permission (PL_WAKEUP_SOFT)
  2125. X *    0    Lock set (PL_SET)
  2126. X *    1    Lock not set (PL_SET)  (another is running)
  2127. X *    1       Locked and running (PL_WAKEUP)
  2128. X *    pid    Locked and running (PL_CHECK)
  2129. X */
  2130. X
  2131. Xproto_lock(prog, command)
  2132. X{
  2133. X    FILE *m_pid;
  2134. X    int try, pid;
  2135. X    char buf[10], *any, *lock;
  2136. X
  2137. X    switch (prog) {
  2138. X     case I_AM_MASTER:
  2139. X     case I_AM_EXPIRE:
  2140. X    lock = relative(master_directory, "MPID");
  2141. X    break;
  2142. X     case I_AM_SPEW:
  2143. X    lock = relative(master_directory, "WPID");
  2144. X    break;
  2145. X#ifdef ACCOUNTING
  2146. X     case I_AM_ACCT:
  2147. X    lock = relative(db_directory, "LCK..acct");
  2148. X    break;
  2149. X#endif
  2150. X     case I_AM_NN:
  2151. X    lock = relative(nn_directory, "LOCK");
  2152. X    break;
  2153. X     default:
  2154. X    sys_error("Invalid LOCK prog");
  2155. X    }
  2156. X
  2157. X    if (command == PL_TRANSFER) {
  2158. X    m_pid = open_file(lock, OPEN_UPDATE|MUST_EXIST);
  2159. X    fprintf(m_pid, "%d\n", process_id);
  2160. X    fclose(m_pid);
  2161. X    return 1;
  2162. X    }
  2163. X
  2164. X    if (command == PL_CLEAR)
  2165. X    goto rm_lock;
  2166. X
  2167. X    try = 1;
  2168. X again:
  2169. X
  2170. X    m_pid = open_file(lock, OPEN_READ);
  2171. X    if (m_pid == NULL) goto no_lock;
  2172. X    any = fgets(buf, 10, m_pid);
  2173. X    fclose(m_pid);
  2174. X
  2175. X    if (any == NULL || (pid = atoi(buf)) <= 2) {
  2176. X    /* lock file is corrupted! */
  2177. X    if (who_am_i == I_AM_NN) goto rm_lock;
  2178. X    if (--try < 0) goto rm_lock;
  2179. X    sleep(LOCK_SAFETY);    /* maybe it is being written */
  2180. X    goto again;
  2181. X    }
  2182. X
  2183. X    if (kill(pid, command == PL_TERMINATE ? SIGHUP : SIGALRM) == 0) {
  2184. X    switch (command) {
  2185. X     case PL_SET_QUICK:
  2186. X        sleep(1);
  2187. X        goto again;
  2188. X
  2189. X     case PL_SET_WAIT:
  2190. X     case PL_CLEAR_WAIT:
  2191. X        sleep(30);
  2192. X        goto again;
  2193. X
  2194. X     case PL_CHECK:
  2195. X        return pid;
  2196. X
  2197. X     default:
  2198. X        return 1;
  2199. X    }
  2200. X    }
  2201. X
  2202. X    if (command == PL_CHECK)
  2203. X    return (errno == EPERM) ? pid : -1;
  2204. X    if (command == PL_WAKEUP_SOFT)
  2205. X    return (errno == EPERM) ? 0 : -1;
  2206. X
  2207. X    /* lock file contains a non-existing process, or a process with */
  2208. X    /* wrong owner, ie. neither master or expire, so remove it */
  2209. X
  2210. X rm_lock:
  2211. X    unlink(lock);
  2212. X
  2213. X no_lock:
  2214. X    if (command != PL_SET && command != PL_SET_QUICK && command != PL_SET_WAIT)
  2215. X    return -1;
  2216. X
  2217. X    m_pid = open_file(lock, OPEN_CREATE);
  2218. X    if (m_pid == NULL) return 1;    /* failed to lock (permission?) */
  2219. X    fprintf(m_pid, "%d\n", process_id);
  2220. X    fclose(m_pid);
  2221. X
  2222. X    /* a user will not start nn twice at the exact same time! */
  2223. X    if (who_am_i == I_AM_NN || command == PL_SET_QUICK) return 0;
  2224. X
  2225. X    sleep(LOCK_SAFETY);
  2226. X
  2227. X    m_pid = open_file(lock, OPEN_READ);
  2228. X    if (m_pid == NULL) return 1; /* somebody stole the lock file */
  2229. X    any = fgets(buf, 10, m_pid);
  2230. X    fclose(m_pid);
  2231. X
  2232. X    if (any == NULL || atoi(buf) != process_id) return 1;
  2233. X
  2234. X    return 0;    /* lock is set */
  2235. X}
  2236. X
  2237. Xsend_master(command, gh, opt, arg)
  2238. Xchar command;
  2239. Xgroup_header *gh;
  2240. Xchar opt;
  2241. Xlong arg;
  2242. X{
  2243. X    FILE *gate;
  2244. X
  2245. X    gate = open_file(relative(master_directory, "GATE"), OPEN_APPEND);
  2246. X
  2247. X    if (gate == NULL) {
  2248. X    printf("Cannot send to master (check GATE file)\n");
  2249. X    return;
  2250. X    }
  2251. X
  2252. X    fprintf(gate, "%c;%ld;%c;%ld;%s %s;\n",
  2253. X        command, gh == NULL ? -1L : gh->group_num, opt, arg,
  2254. X        user_name(), date_time((time_t)0));
  2255. X
  2256. X    fclose(gate);
  2257. X
  2258. X    log_entry('A', "SEND %c %s %c %ld",
  2259. X          command, gh == NULL ? "(all)" : gh->group_name, opt, arg);
  2260. X
  2261. X    if (who_am_i == I_AM_ADMIN)
  2262. X    proto_lock(I_AM_MASTER, PL_WAKEUP_SOFT);
  2263. X}
  2264. X
  2265. END_OF_FILE
  2266.   if test 3702 -ne `wc -c <'proto.c'`; then
  2267.     echo shar: \"'proto.c'\" unpacked with wrong size!
  2268.   fi
  2269.   # end of 'proto.c'
  2270. fi
  2271. echo shar: End of archive 19 \(of 22\).
  2272. cp /dev/null ark19isdone
  2273. MISSING=""
  2274. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ; do
  2275.     if test ! -f ark${I}isdone ; then
  2276.     MISSING="${MISSING} ${I}"
  2277.     fi
  2278. done
  2279. if test "${MISSING}" = "" ; then
  2280.     echo You have unpacked all 22 archives.
  2281.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2282. else
  2283.     echo You still must unpack the following archives:
  2284.     echo "        " ${MISSING}
  2285. fi
  2286. exit 0
  2287.  
  2288. exit 0 # Just in case...
  2289.